package com.example.demo.service.impl;

import com.example.demo.entity.ResourceFile;
import com.example.demo.mapper.ResourceFileMapper;
import com.example.demo.service.ResourceFileService;
import com.example.demo.unitls.UploadFileUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 资源服务实现
 *
 * @author 叮当猫的百宝箱
 * @since 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ResourceFileServiceImpl implements ResourceFileService {

    private final ResourceFileMapper resourceFileMapper;
    private final UploadFileUtils uploadFileUtils;



    /**
     * 文件上传保存的路径; 要求使用绝对路径
     */
    @Value("${erp.resource.dir:/uploads}")
    private String uploadDir;

    /**
     * 初始化资源上传路径
     * 如果资源上传路径不存在，则创建文件夹
     */
    @PostConstruct
    private void initResourcePath() {
        File dir = new File(uploadDir);
        if (!dir.exists()) {
            boolean created = dir.mkdirs();
            if (!created) {
                throw new RuntimeException("初始化资源目录失败");
            }
        }
        log.info("Resource upload path initialized: {}", uploadDir);
    }

    /**
     * 根据资源ID获取资源详情
     *
     * @param id 资源ID
     * @return 资源详情信息
     */
    @Override
    public ResourceFile getResourceById(Long id) {
        return resourceFileMapper.findById(id);
    }

    /**
     * 添加资源文件
     *
     * @param resource 待添加的资源信息
     */
    @Override
    public void create(ResourceFile resource) {
        LocalDateTime now = LocalDateTime.now();
        resource.setUsed(0);
        resource.setDeleted(0);
        resource.setCreateTime(now);
        resource.setUpdateTime(now);
        resourceFileMapper.insert(resource);
    }

    /**
     * 清除上传后长期未使用的资源(每天00:30自动执行)
     */
    @Override
    @Scheduled(cron = "0 30 0 * * *")
    public void clear() {
        LocalDateTime invalidTime = LocalDateTime.now().minusDays(3L);
        List<ResourceFile> invalidAll = resourceFileMapper.findInvalidAll(invalidTime);
        for (ResourceFile resource : invalidAll) {
            delete(resource);
        }
    }

    /**
     * 根据资源ID删除资源信息(同时删除文件)
     *
     * @param id 资源ID
     */
    @Override
    public void deleteById(Long id) {
        ResourceFile resource = getResourceById(id);
        if (resource != null) {
            delete(resource);
        }
    }

    /**
     * 删除资源信息(同时删除文件)
     *
     * @param resource 待删除资源信息
     */
    @Override
    public void delete(ResourceFile resource) {
        String path = uploadDir + File.separator + resource.getPath();
        File file = new File(path);
        if (file.exists()) {
            boolean deleted = file.delete();
            if (deleted) {
                markAsDeletedById(resource.getId());
            }
        }
        markAsDeletedById(resource.getId());
    }

    /**
     * 根据资源ID将资源信息标记为已删除(仅标记不删除文件)
     *
     * @param id 资源ID
     */
    @Override
    public void markAsDeletedById(Long id) {
        resourceFileMapper.markAsDeletedById(id, LocalDateTime.now());
    }

    /**
     * 将资源信息标记为已使用
     *
     * @param id 资源ID
     */
    @Override
    public void markAsUsedById(Long id) {
        resourceFileMapper.markAsUsedById(id);
    }

    /**
     * 将资源信息标记为未使用
     *
     * @param id 资源ID
     */
    @Override
    public void markAsNotUsedById(Long id) {
        resourceFileMapper.markAsNotUsedById(id);
    }

    /**
     * 上传图片
     *
     * @param file 待上传的图片文件
     * @return 文件在服务器中的资源信息
     */
    public ResourceFile uploadImage(MultipartFile file) {
        if (file.isEmpty()) {
            throw new RuntimeException("Please select a file to upload");
        }
        try {
            byte[] fileBytes = file.getBytes();
            String mimeType = uploadFileUtils.getMimeType(fileBytes);
            List<String> allowMimeType = new ArrayList<>();
            allowMimeType.add("image/jpeg");
            allowMimeType.add("image/jpg");
            allowMimeType.add("image/png");

            if (!allowMimeType.contains(mimeType)) {
                throw new RuntimeException("不允许的文件类型");
            }

            String extension = uploadFileUtils.getFileExtensionFromMimeType(mimeType);
            String fileName = UUID.randomUUID() + "." + extension;

            Path filePath = Paths.get(uploadDir + File.separator + fileName);
            Files.write(filePath, fileBytes);
            // 向资源表插入数据
            ResourceFile resource = new ResourceFile();
            resource.setPath(fileName);
            resource.setType("IMAGE");
            resource.setSize(Long.toString(file.getSize()));
            create(resource);
            return resource;
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

}
